#include <cstdio>
#include <cstdint>
#include <cerrno>
#include <thread>
#include <chrono>
#include <cmath>
#include <algorithm>
#include <atomic>
#include <vector>
#include <iterator>
#include <string>

#include "simple/support/misc.hpp"
#include "simple/musical/initializer.h"
#include "simple/musical/device.h"

#if SDL_VERSION_ATLEAST(2,0,5)

using namespace simple::musical;
using namespace std::literals;

int main(int argc, const char** argv) try
{

	switch(argc)
	{
		case 0: std::puts("command not specified??");
		case 1: std::puts("file not specified");
		case 2: std::puts("duration not specified");
			return -1;
	}

	initializer init;

    std::vector<std::uint8_t> output;
	output.reserve(10000);

	const auto duration = simple::support::ston<int>(argv[2]);

	std::atomic<bool> done = false;
	device_with_callback player
	(
		basic_device_parameters{ spec{} }.set_capture(true),
		[&duration, &done, &output, i = std::back_inserter(output)](auto& device, auto buffer) mutable
		{
			std::copy(buffer.begin(), buffer.end(), i);
			auto obtained = device.obtained();
			const std::size_t target_size = obtained.get_frequency() * duration * (int)obtained.get_channels() * byte_size(obtained.get_format());
			if(output.size() >= target_size)
				done = true;
		}
	);

	player.play();

	while(!done)
		std::this_thread::sleep_for(50ms);

	auto file = fopen(argv[1], "w");
    std::fwrite(output.data(), 1, output.size(), file);
	fclose(file);

	std::puts(("Format: "s + to_c_str(player.obtained().get_format())).c_str());
	std::puts(("Channels: " + std::to_string((int)player.obtained().get_channels())).c_str());
	std::puts(("Frequency: " + std::to_string(player.obtained().get_frequency())).c_str());

	return 0;
}
catch(...)
{
	if(errno)
		std::perror("ERROR");

	const char* sdl_error = SDL_GetError();
	if(*sdl_error)
		std::puts(sdl_error);

	throw;
}

#else
int main()
{
	std::puts("SDL 2.0.5 ot higher required!");
	return 0;
}
#endif

